package com.example.jdk8.lambdaStream;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Java8Test1 {

    public static void main(String[] args) {

        String[] str = {"TaoBao", "ZhiFuBao", "Tmall"};

        //这里省略list的构造
        List<String> names = Arrays.asList(str);

        //使用lambda表达式来排序
        Collections.sort(names, (o1, o2) -> o1.compareTo(o2));

        //使用匿名内部类来排序
//        Collections.sort(names, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareTo(o2);
//            }
//        });


        System.out.println(names);

        //普通青年
//        List<String> lowercaseNames = new ArrayList<>();
//        for (String name : names) {
//            lowercaseNames.add(name.toLowerCase());
//        }

        //文艺青年的代码（借助Guava）：
//        List<String> lowercaseNames1 = FluentIterable.from(names).transform(new Function<String, String>() {
//            @Override
//            public String apply(String name) {
//                return name.toLowerCase();
//            }
//        }).toList();


//        List<String> lowercaseNames = names.stream().map((String name) ->{return  name.toLowerCase();} ).collect(Collectors.toList());
        //1、参数类型省
//        List<String> lowercaseNames = names.stream().map(( name) ->{return  name.toLowerCase();} ).collect(Collectors.toList());
        //2、当lambda表达式的参数个数只有一个，可以省略小括号
//        List<String> lowercaseNames = names.stream().map( name ->{return  name.toLowerCase();} ).collect(Collectors.toList());
        //3、当lambda表达式只包含一条语句时，可以省略大括号、return和语句结尾的分号
//        List<String> lowercaseNames= names.stream().map( name ->  name.toLowerCase()).collect(Collectors.toList());
        //4、使用Method Reference(具体语法后面介绍)
        List<String> lowercaseNames = names.stream().map(String::toLowerCase).collect(Collectors.toList());

        System.out.println(lowercaseNames);


        String[] array = {"a", "b", "c"};
        for (Integer i : Lists.newArrayList(1, 2, 3)) {
            Stream.of(array).map(item -> Strings.padEnd(item, i, '@')).forEach(System.out::println);
        }


        /* lambda表达式的三个重要组成部分：
        输入参数、可执行语句、存放外部变量的空间
        不过lambda表达式访问外部变量有一个非常重要的限制：变量不可变（只是引用不可变，而不是真正的不可变）。

        java的匿名内部类在访问外部变量的时候，外部变量必须用final修饰

        方法引用语法格式有以下三种：
        objectName::instanceMethod
        ClassName::staticMethod
        ClassName::instanceMethod
        前两种方式类似，等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。
        比如System.out::println等同于x->System.out.println(x)；Math::max等同于(x, y)->Math.max(x,y)。

        最后一种方式，等同于把lambda表达式的第一个参数当成instanceMethod的目标对象，其他剩余参数当成该方法的参数。
        比如String::toLowerCase等同于x->x.toLowerCase()。
        */
        List<Character> lowercaseNames1 = names.stream().map(name -> name.charAt(0)).collect(Collectors.toList());
        System.out.println(lowercaseNames1);


//        mlist.forEach( System.out :: println );
//        	mlist.forEach( n->System.out.println(n) );
//        	mlist.forEach( n->{
//        		System.out.println(n);
//        	});

        double[] population = {40 , 30 , 50 , 80 };
        System.out.println("avg-"+varianceStreams(population));


    }


    public static double varianceStreams(double[] population) {
        double average = Arrays.stream(population).parallel().average().orElse(0.0);
        double variance = Arrays.stream(population).parallel()
                .map(p -> (p - average) * (p - average))
                .sum() / population.length;
        return variance;
    }


}